/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */

#ifndef __WMO_GROUP_FILE_H__
#define __WMO_GROUP_FILE_H__

#include "OgreString.h"
#include "OgreVector2.h"
#include "OgreVector3.h"
#include "OgreVector4.h"

#include "WowCommon.h"
#include "FileBase.h"

namespace PQGameCore
{
	/*
	Offset 	Type 		Description
	0x00 	unsigned int 		nMaterials - number of materials
	0x04 	unsigned int 		nGroups - number of WMO groups
	0x08 	unsigned int 		nPortals - number of portals
	0x0C 	unsigned int 		nLights - number of lights
	0x10 	unsigned int 		nModels - number of M2 models imported
	0x14 	unsigned int 		nDoodads - number of dedicated files (*see below this table!) 
	0x18 	unsigned int 		nSets - number of doodad sets
	0x1C 	unsigned int 		ambient color?
	0x20 	unsigned int 		WMO ID (column 2 in WMOAreaTable.dbc)
	0x24 	float[3]		Bounding box corner 1
	0x30 	float[3]	 	Bounding box corner 2
	0x3C 	unsigned int 		LiquidType related, see below in the MLIQ chunk.
	*/
	typedef struct _wmo_mohd{
		unsigned int nMaterials ;
		unsigned int nGroups;
		unsigned int nPortals;
		unsigned int nLights;
		unsigned int nModels;//
		unsigned int nDoodads;
		unsigned int nDoodadSets;
		unsigned int ambientColor;
		unsigned int wmoId;
		float bbox1[3];
		float bbox2[3];
		unsigned int liquidType;
	}wmo_mohd;

	typedef struct _wmo_momt{
		int flags;
		int specular;
		int transparent; // Blending: 0 for opaque, 1 for transparent
		int name1; // Start position for the first texture filename in the MOTX data block	
		unsigned int col1; // color
		int d3; // flag
		int name2; // Start position for the second texture filename in the MOTX data block
		unsigned int col2; // color
		int d4; // flag
		unsigned int col3;
		float f2;
		float diffColor[3];
		int texture1; // this is the first texture object. of course only in RAM. leave this alone. :D
		int texture2; // this is the second texture object.
	}wmo_momt;

	/*
	0x00 	unsigned int 		Flags
	0x04 	3 * float 	Bounding box corner 1
	0x10 	3 * float 	Bounding box corner 2
	0x1C 	int 		name in MOGN chunk (or -1 for no name?)
	*/
	typedef struct _wmo_mogi{
		unsigned int flags;
		float  bbox1[3];
		float  bbox2[3];
		int nameoffset;
	}wmo_mogi;

	/*
	Portal <> group relationship? 2*nPortals entries of 8 bytes.
	I think this might specify the two WMO groups that a portal connects.
	*/
	typedef struct _wmo_mopr {
		short portal, group, dir, reserved;
	}wmo_mopr;

	/*
	Offset 	Type 		Description
	0x00 	4 * unsigned char 	Flags or something? Mostly (0,1,1,1)
	0x04 	4 * unsigned char 	Color (B,G,R,A)
	0x08 	3 * float 	Position (X,Z,-Y)
	0x14 	7 * float 	Unknown (light properties?)
	*/

	typedef struct _wmo_molt{
		unsigned char lightType;
		unsigned char type;
		unsigned char useAtten;
		unsigned char pad;

		unsigned int color;
		Ogre::Vector3 position;
		
		float intensity;
		float attenStart;
		float attenEnd;
		float unk[4];

	}wmo_molt;

	typedef struct _wmo_mods {
		char name[20]; // Set name
		int start; // index of first doodad instance in this set
		int size; // number of doodad instances in this set
		int unused; // always 0
	}wmo_mods;

	typedef struct _wmo_modd{
		unsigned int nameIndex;
		float pos[3];
		float rot[4];
		float scale;
		unsigned int color;
	}wmo_modd;

	typedef struct _wmo_mfog {
		unsigned int flags;
		float pos[3];
		float r1; // Smaller radius
		float r2; // Larger radius
		float fogend; // Fog end
		float fogstart; // Fog start multiplier (0..1)
		unsigned int color1; // The back buffer is also cleared to this colour 
		float f2; // Unknown (almost always 222.222)
		float f3; // Unknown (-1 or -0.5)
		unsigned int color2;
	}wmo_mfog;

	/*
	Offset	Type		Description
	0x00 	unsigned int 		Group name (offset into MOGN chunk)
	0x04 	unsigned int 		Descriptive group name (offset into MOGN chunk)
	0x08 	unsigned int 		Flags
	0x0C 	float[3] 	Bounding box corner 1 (same as in MOGI)
	0x18 	float[3] 	Bounding box corner 2
	0x24 	unsigned int 		Index into the MOPR chunk
	0x26 	unsigned int 		Number of items used from the MOPR chunk
	0x28 	unsigned int 		Number of batches A
	0x2A 	unsigned int 		Number of batches B
	0x2C 	unsigned int 		Number of batches C
	0x30 	unsigned char[4] 	Up to four indices into the WMO fog list
	0x34 	unsigned int 		LiquidType related, see below in the MLIQ chunk.
	0x38 	unsigned int 		WMO group ID (column 4 in WMOAreaTable.dbc)
	0x3C 	unsigned int 		Always 0?
	0x40 	unsigned int 		Always 0?
	*/

	typedef struct _wmo_mogp {
		int nameStart;
		int nameStart2;
		int flags;
		float bbox1[3];
		float bbox2[3]; 
		short portalStart;
		short portalCount;
		short batches[4];
		unsigned char fogs[4];
		int unk1;// LiquidType related, see below in the MLIQ chunk.
		int id;
		int unk2;
		int unk3;
	}wmo_mogp;

	typedef struct _wmo_mopy {
		unsigned char flags;
		unsigned char mtlId;
	}wmo_mopy;

	typedef struct _wmo_moba {
		char bytes[12];
		unsigned int indexStart;
		unsigned int indexCount, vertexStart, vertexEnd;
		unsigned char flags, texture;
	}wmo_moba;

	class WMOFile;
	/*
	MO group files contain the actual polygon soup for a particular section of the entire WMO.
	Every group file has one top-level MOGP chunk, that has a 68-byte header followed by more subchunks. 
	So it can be effectively treated as a file with a header at 0x14 and chunks starting at 0x58.
	The subchunks are not always present. Some are fixed and needed while others are only checked for if some flags in the header are set. 
	The chunks need to be in the right order if you want WoW to read it.
	*/
	class WMOGroupFile
	{
	private:
		PQEngine::FileBase *file;
		int version;
		char* name;//description name?
		int id;
	public:
		WMOFile *wmo;
		wmo_mogi *mogi;//map object info
		WMOGroupFile(PQEngine::FileBase *f,WMOFile *parser, int index,wmo_mogi *ogi,char* mogn);
		void init(PQEngine::FileBase *f);

		wmo_mogp *mogp;
		int fog;
		void initMOGP(PQEngine::FileBase *f,int size);

		wmo_mopy *mopys;
		int mopyCount;
		void initMOPY(PQEngine::FileBase *f,int size);

		unsigned short* movis;
		int moviCount;
		void initMOVI(PQEngine::FileBase *f,int size);//

		Ogre::Vector3 *movts;
		int movtCount;//size in byte,count in obj
		void initMOVT(PQEngine::FileBase *f,int size);

		Ogre::Vector3 *monrs;//normal data
		int monrCount;//normal count
		void initMONR(PQEngine::FileBase *f,int size);

		Ogre::Vector2 *motvs;
		int motvCount;//map object texture coordinates
		void initMOTV(PQEngine::FileBase *f,int size);

		wmo_moba* mobas;
		int mobaCount;
		void initMOBA(PQEngine::FileBase *f,int size);

		short* molrs;
		int molrCount;
		void initMOLR(PQEngine::FileBase *f,int size);

		short* modrs;
		int modrCount;
		void initMODR(PQEngine::FileBase *f,int size);
		
		unsigned int* mocvs;
		int mocvCount;
		void initMOCV(PQEngine::FileBase *f,int size);
	};
}
#endif
